package cn.lijian.goods.order.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.itcast.commons.CommonUtils;
import cn.itcast.servlet.BaseServlet;
import cn.lijian.goods.book.domain.Book;
import cn.lijian.goods.cart.domain.CartItem;
import cn.lijian.goods.cart.service.CartItemService;
import cn.lijian.goods.order.domain.Order;
import cn.lijian.goods.order.domain.OrderItem;
import cn.lijian.goods.order.service.OrderService;
import cn.lijian.goods.pager.PageBean;
import cn.lijian.goods.user.domain.User;

public class OrderServlet extends BaseServlet {

	private OrderService orderService=new OrderService();
	private CartItemService cartItemService=new CartItemService();
	
	/**
	 * 获取当前页的页码
	 * @param request
	 * @return
	 * @author lijian
	 */
	private int getPageCurrent(HttpServletRequest request){
		int pc=1;
		String param=request.getParameter("pc");
		if(param!=null&&!param.trim().isEmpty()){
			try {
				pc=Integer.parseInt(param);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return pc;
	}
	
	/**
	 * 
	 * 截取 URL 页面中的分页导航中需要使用它作为超链接的目标
	 * @param request
	 * @return
	 * @author lijian
	 */
	private String getUrl(HttpServletRequest request){
		//假设请求是   http://localhost:8080/goods/jsps/xx?sssss=s&sss=s
		String uri=request.getRequestURI();//   /goods/jsps/xx
		String str=request.getQueryString();//   xx?sssss=s&sss=s
		uri=uri+"?"+str;
		//如果 URL 中存在 pc 参数，截取掉，如果没有就行
		
		int index=uri.lastIndexOf("&pc");
		if(index!=-1){
			uri=uri.substring(0,index);
		}
		return uri;
	}

	/**
	 * 我的订单
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String myOrders(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//得到 pageCurrent，如果页面传递，获取，如果没有，设置 1
		int pc=getPageCurrent(request);
		//得到 URL 
		String url=getUrl(request);
		//得到查询条件
		User user=(User)request.getSession().getAttribute("sessionUser");
		
		//使用 service 查询,得到 pagebean
		PageBean<Order>pageBean=orderService.myOrders(user.getUid(), pc);
		//给pagebean 设置 URL 
		pageBean.setUrl(url);
		request.setAttribute("pb", pageBean);
		return "f:/jsps/order/list.jsp";
	}
	/**
	 * 生成订单
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String createOrder(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取所有购物车条目的 ID 并查询
		String cartItemIds=request.getParameter("cartItemIds");
		List<CartItem> cartItemList=cartItemService.loadCartItem(cartItemIds);
		// 创建订单 order
		Order order=new Order();
		order.setOid(CommonUtils.uuid());
		order.setOrdertime(String.format("%tF %<tT", new Date()));//设置下单时间
		order.setStatus(1);//设置状态 1 ，表示 未付款
		order.setAddress(request.getParameter("address"));
		User user=(User)request.getSession().getAttribute("sessionUser");
		order.setOwner(user);
		
		BigDecimal total=new BigDecimal("0");
		for(CartItem cartItem : cartItemList){
			total=total.add(new BigDecimal(cartItem.getSubtotal()+""));
		}
		order.setTotal(total.doubleValue());
		// 创建订单条目 orderItemList
		List<OrderItem>orderItemList=new ArrayList<OrderItem>();
		for(CartItem cartItem:cartItemList){
			OrderItem orderItem=new OrderItem();
			orderItem.setOrderItemId(CommonUtils.uuid());
			orderItem.setQuantity(cartItem.getQuantity());
			orderItem.setSubtotal(cartItem.getSubtotal());
			orderItem.setBook(cartItem.getBook());
			orderItem.setOrder(order);
			orderItemList.add(orderItem);
		}
		order.setOrderItemList(orderItemList);
		
		orderService.createOrder(order);
		
		//删除购物车条目
		cartItemService.batchDelete(cartItemIds);
		request.setAttribute("order", order);
		return "f:/jsps/order/ordersucc.jsp";
		
	}
	/**
	 * 加载订单
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String load(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String oid=request.getParameter("oid");
		Order order=orderService.load(oid);
		request.setAttribute("order", order);
		String btn=request.getParameter("btn");//说明了用户点击 哪个超链接来访问本方法的
		request.setAttribute("btn", btn);
		return "f:/jsps/order/desc.jsp";
		
	}
	/**
	 * 取消订单
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String cancle(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String oid=request.getParameter("oid");
		int status=orderService.findStatus(oid);
		if(status!=1){
			request.setAttribute("code", "error");
			request.setAttribute("msg","订单状态不对，不能取消");
			return "f:/jsps/msg.jsp";
		}else{
			orderService.updateStatus(oid, 5);//设置状态为取消
			request.setAttribute("code", "success");
			request.setAttribute("msg", "订单已取消");
			return "f:/jsps/msg.jsp";
		}
	}
	
	/**
	 * 确认收货
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String confirm(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String oid=request.getParameter("oid");
		int status=orderService.findStatus(oid);
		if(status!=3){
			request.setAttribute("code", "error");
			request.setAttribute("msg","订单状态不对，不能确认收货");
			return "f:/jsps/msg.jsp";
		}else{
			orderService.updateStatus(oid, 4);//设置状态为交易成功
			request.setAttribute("code", "success");
			request.setAttribute("msg", "恭喜交易成功");
			return "f:/jsps/msg.jsp";
		}
	}
	
	/**
	 * 支付准备
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String paymentPre(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String oid=request.getParameter("oid");
		Order order=orderService.load(oid);
		request.setAttribute("order", order);
		return "f:jsps/order/pay.jsp";
	}
	
	/**
	 * 支付
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String payment(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		Properties props=new Properties();
		props.load(this.getClass().getClassLoader().getResourceAsStream("payment.properties"));
		
		//准备 13 个参数
		String p0_Cmd="Buy";//业务类型，固定值
		String p1_MerId = props.getProperty("p1_MerId");//商号编码，在易宝的唯一标识
		String p2_Order = request.getParameter("oid");//订单编码
		String p3_Amt = "0.01";//支付金额
		String p4_Cur = "CNY";//交易币种，固定值CNY
		String p5_Pid = "";//商品名称
		String p6_Pcat = "";//商品种类
		String p7_Pdesc = "";//商品描述
		String p8_Url = props.getProperty("p8_Url");//在支付成功后，易宝会访问这个地址。
		String p9_SAF = "";//送货地址
		String pa_MP = "";//扩展信息
		String pd_FrpId = request.getParameter("yh");//支付通道
		String pr_NeedResponse = "1";//应答机制，固定值1
		
		//计算 hmac 需要 13 个参数 还需要 keyValue ,还需要 加密算法
		String keyValue = props.getProperty("keyValue");
		
		String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt,
				p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP,
				pd_FrpId, pr_NeedResponse, keyValue);
		
		//重定向到 易宝 的支付网关
		StringBuilder sb = new StringBuilder("https://www.yeepay.com/app-merchant-proxy/node");
		sb.append("?").append("p0_Cmd=").append(p0_Cmd);
		sb.append("&").append("p1_MerId=").append(p1_MerId);
		sb.append("&").append("p2_Order=").append(p2_Order);
		sb.append("&").append("p3_Amt=").append(p3_Amt);
		sb.append("&").append("p4_Cur=").append(p4_Cur);
		sb.append("&").append("p5_Pid=").append(p5_Pid);
		sb.append("&").append("p6_Pcat=").append(p6_Pcat);
		sb.append("&").append("p7_Pdesc=").append(p7_Pdesc);
		sb.append("&").append("p8_Url=").append(p8_Url);
		sb.append("&").append("p9_SAF=").append(p9_SAF);
		sb.append("&").append("pa_MP=").append(pa_MP);
		sb.append("&").append("pd_FrpId=").append(pd_FrpId);
		sb.append("&").append("pr_NeedResponse=").append(pr_NeedResponse);
		sb.append("&").append("hmac=").append(hmac);
		
		response.sendRedirect(sb.toString());
		return null;
	}
	
	/**
	 * 支付成功时，易宝会访问这里
	 * 	用两种方法访问
	 * 		重定向 ： 如果用户关闭了浏览器，就无法访问了
	 * 		易宝服务器会使用点对点通讯的方法访问这个方法，这个方法必须回馈 success ， 否则会一直访问
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 * @author lijian
	 */
	public String back(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 1. 获取12个参数
		 */
		String p1_MerId = request.getParameter("p1_MerId");
		String r0_Cmd = request.getParameter("r0_Cmd");
		String r1_Code = request.getParameter("r1_Code");
		String r2_TrxId = request.getParameter("r2_TrxId");
		String r3_Amt = request.getParameter("r3_Amt");
		String r4_Cur = request.getParameter("r4_Cur");
		String r5_Pid = request.getParameter("r5_Pid");
		String r6_Order = request.getParameter("r6_Order");
		String r7_Uid = request.getParameter("r7_Uid");
		String r8_MP = request.getParameter("r8_MP");
		String r9_BType = request.getParameter("r9_BType");
		String hmac = request.getParameter("hmac");
		/*
		 * 2. 获取keyValue
		 */
		Properties props = new Properties();
		props.load(this.getClass().getClassLoader().getResourceAsStream("payment.properties"));
		String keyValue = props.getProperty("keyValue");
		/*
		 * 3. 调用PaymentUtil的校验方法来校验调用者的身份
		 *   >如果校验失败：保存错误信息，转发到msg.jsp
		 *   >如果校验通过：
		 *     * 判断访问的方法是重定向还是点对点，如果要是重定向
		 *     修改订单状态，保存成功信息，转发到msg.jsp
		 *     * 如果是点对点：修改订单状态，返回success
		 */
		boolean bool = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, r1_Code, r2_TrxId,
				r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid, r8_MP, r9_BType,
				keyValue);
		if(!bool) {
			request.setAttribute("code", "error");
			request.setAttribute("msg", "无效的签名，支付失败！（你不是好人）");
			return "f:/jsps/msg.jsp";
		}
		if(r1_Code.equals("1")) {
			orderService.updateStatus(r6_Order, 2);
			if(r9_BType.equals("1")) {//重定向
				request.setAttribute("code", "success");
				request.setAttribute("msg", "恭喜，支付成功！");
				return "f:/jsps/msg.jsp";				
			} else if(r9_BType.equals("2")) {//服务器点对点
				response.getWriter().print("success");
			}
		}
		return null;
	}
	

}
